/**
 * @author Shine
 */

package com.shine.utils
{
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.MovieClip;
	import flash.geom.Rectangle;
	
	public class DisplayObjectUtil
	{
		/**
		 * Scale and fit a movieclip to fit within a rectangle.  This will keep the aspect ratio of the clip.
		 * 
		 * @paramtargetthe movieclip to fit.
		 * @paramleftLeft area.
		 * @paramtopTop of the area.
		 * @paramwidthWidth of the area.
		 * @paramheightHeight of the area.
		 * @paramalignmentAlignment of the target in the space.
		 * 0x0 center / middle aligned.
		 * 0x1 left 
		 * 0x2 right 
		 * 0x4 top 
		 * 0x8 bottom   
		 * @param scaleModespecs how the target scales within the area.
		 * current supported
		 * none
		 * fit(default)
		 * 
		 * planned
		 * fitup
		 * fith
		 * fitv
		 * fill fill the entire area with the image.
		 */
		public static  function scaleToArea(target:DisplayObject,left:Number,top:Number,width:Number,height:Number,alignment:Number=0,scaleMode:String="fit"):void 
		{
			//reset the previous scale.
			target.scaleX=target.scaleY=1;
			
			var bounds:Rectangle=target.getBounds(target);
			
			var scale:Number=Number((Math.min(width / target.width,height / target.height)).toFixed(4));

			target.scaleX=scale;
			target.scaleY=scale;
			
			target.x=left+(width - target.width) * (alignment & 3?alignment & 1?0:1:0.5) - bounds.x;
			target.y=top+(height - target.height) * (alignment & 12?alignment & 4?0:1:0.5) - bounds.y;
			
		}
		
		public static  function removeAllChildren(container:DisplayObjectContainer):void 
		{
            if(container==null) return;
			// Because the numChildren value changes after every time we remove
			// a child, save the original value so we can count correctly
			if(container is MovieClip) MovieClip(container).stop();
			
			var count:int=container.numChildren;

			// Loop over the children in the container and remove them
			for (var i:int=0; i < count; i++) {
				container.removeChildAt(0) as DisplayObjectContainer;
			}
		}
		
		public static  function getContainerChildren(container:DisplayObjectContainer):Array
		{
			var returnArr:Array=new Array();
			
			if(container.numChildren<1) return returnArr;
			
			for (var i:uint=0; i < container.numChildren; i++)
			{
				var item:DisplayObject=container.getChildAt(i);
				returnArr.push(item);
			}
			return returnArr;
		}
		
		public static  function getContainerRect(container:DisplayObjectContainer):Rectangle
		{
			var targetCoordinate:DisplayObject=container.parent ? container.parent : container;
			
			var maxX:int=0;
			var maxY:int=0;
			var minX:int=int.MAX_VALUE;
			var minY:int=int.MAX_VALUE;
			
			var rect2:Rectangle=container.getBounds(targetCoordinate);
			minX=Math.min(int(rect2.x),minX);
			minY=Math.min(int(rect2.y),minY);
			maxX=Math.max(int(rect2.bottomRight.x),maxX);
			maxY=Math.max(int(rect2.bottomRight.y),maxY);
			
			var list:Array=getAllChildren(container);
			for (var i:uint = 0; i < list.length; i++) 
			{ 
				var rect:Rectangle;
				var child:DisplayObject=list[i].child;
				if(child==null)continue;
				if(child is MovieClip){
					for(var j:uint=1;j<=MovieClip(child).totalFrames;j++)
					{
						MovieClip(child).gotoAndStop(j);
						rect=child.getBounds(targetCoordinate);
						minX=Math.min(int(rect.topLeft.x),minX);
						minY=Math.min(int(rect.topLeft.y),minY);
						maxX=Math.max(int(rect.bottomRight.x),maxX);
						maxY=Math.max(int(rect.bottomRight.y),maxY);
					}
				}else{
					rect=child.getBounds(targetCoordinate);
					minX=Math.min(int(rect.topLeft.x),minX);
					minY=Math.min(int(rect.topLeft.y),minY);
					maxX=Math.max(int(rect.bottomRight.x),maxX);
					maxY=Math.max(int(rect.bottomRight.y),maxY);
				}
			}
			
			return new Rectangle(minX,minY,(maxX-minX),(maxY-minY));
		}
		
		public static  function getAllChildren(container:DisplayObjectContainer):Array
		{
			if(container==null) return [];
			var children:Children=new Children();
			children.getChildren(container);
			return children.list;
		}
		
		public static  function getAllChildMC(container:DisplayObjectContainer):Array
		{
			if(container==null) return [];
			var children:Children=new Children();
			children.getChildMC(container);
			return children.list;
		}
		
		public static function copyAttribute(target:DisplayObject,obj:DisplayObject):void
		{
			target.x=obj.x;
			target.y=obj.y;
			target.width=obj.width;
			target.height=obj.height;
			target.scaleX=obj.scaleX;
			target.scaleY=obj.scaleY;
			target.rotation=obj.rotation;
			target.alpha=obj.alpha;
			target.mask=obj.mask;
			target.transform.colorTransform=obj.transform.colorTransform;
			target.transform.matrix=obj.transform.matrix.clone();
			target.filters=obj.filters.slice();
		}
	}
}

class Children
{
	import flash.display.DisplayObjectContainer;
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	
	internal var list:Array;
	
	function Children(){
		list=new Array();
	}
		
	internal function getChildren(dsObject:DisplayObjectContainer, iDepth:int = 0):void 
	{ 
		var i:int = 0; 
		var dsoChild:DisplayObject; 
		
		for (i = 0; i < dsObject.numChildren ; ++i) 
		{ 
			dsoChild = dsObject.getChildAt(i); 
			
			if(iDepth>0) list.push({child:dsoChild,layel:iDepth});
			
			if (dsoChild is DisplayObjectContainer && DisplayObjectContainer(dsoChild).numChildren>0){
				getChildren(dsoChild as DisplayObjectContainer,++iDepth); 
		    }
		} 
	} 
    
	internal function getChildMC(dsObject:DisplayObjectContainer, iDepth:int = 0):void 
	{ 
		var i:int = 0; 
		var dsoChild:DisplayObject; 
		
		for (i = 0; i < dsObject.numChildren ; ++i) 
		{ 
			dsoChild = dsObject.getChildAt(i); 
			
			if(iDepth>0 && dsoChild && (dsoChild is MovieClip) && MovieClip(dsoChild).totalFrames>1){
				list.push(dsoChild);
			}
			
			if (dsoChild is DisplayObjectContainer && DisplayObjectContainer(dsoChild).numChildren>0){ 
				getChildMC(dsoChild as DisplayObjectContainer,++iDepth); 
			}
				
		} 
	} 
}